/**
* 
* ====================================================================
*
* @author apov <apov@ymail.com>
*/ 
// ProtocolBinder.h
//

#pragma once

#include <BaseDefine.h>
#include <LumpData.h>
#include <DeleteObjInSTL.h>
#include <map>

template <class T>
class ProtocolBinder{
	typedef struct ProtocolAction{
		int (*func)(T*, CLumpData*);
		int check_field;
	};

	typedef std::map<unsigned short, ProtocolAction*> BindContain;

public:
	enum{
		UNREGISTERED=			-1,
		NO_SESSION=				-2,
		NO_NETWORK_DATA=		-3,
	};

	int registerProtocol(unsigned short protocol, \
		int (*func)(T*, CLumpData*), int check_field)
	{
		ProtocolAction* bind = new ProtocolAction();
		bind->func = func;
		bind->check_field = check_field;

		typename std::map<unsigned short, ProtocolAction*>::iterator itr = bind_.find(protocol);
		if( itr != bind_.end() )
			return -1;

		bind_.insert(std::pair<unsigned short, ProtocolAction*>(protocol, bind));

		return bind_.size();
	}

	int checkProtocol(unsigned short protocol, T* session, CLumpData* data){
		if(! session )
			return NO_SESSION;

		if(! data )
			return NO_NETWORK_DATA;

		typename std::map<unsigned short, ProtocolAction*>::iterator itr = bind_.find(protocol);
		if( itr == bind_.end() )
			return UNREGISTERED;

		action_ = (ProtocolAction*)itr->second;
		return action_->check_field;
	}

	int processProtocol( T* session, CLumpData* data ){
		return action_->func(session, data);
	}

	ProtocolBinder(){
		action_ = 0;
	}

	virtual ~ProtocolBinder(){
		DeleteObjInSTL<unsigned short, ProtocolAction>::DeleteMap(bind_);
	}

protected:	

private:
	BindContain bind_;
	ProtocolAction* action_;
};
